// author: shelman
// description：封装了有名管道（FIFO）的接口
#ifndef fifo_util_h
#define fifo_util_h


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)
// 打开模式
#define FIFO_SERVER     0x01
#define FIFO_CLIENT     0x02
#endif


#ifdef __cplusplus
extern "C"
{
#endif

#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)
#define FIFOUTIL_DLL_EXPORT __declspec(dllexport)
#else
#define FIFOUTIL_DLL_EXPORT __attribute__((visibility("default")))
#endif

// 支持有名管道的创建、销毁、打开、关闭，数据读写，数据为字节流。
// 在linux中，有名管道（FIFO）的单次传输数据量受到PIPE_BUF的限制。
// 根据POSIX标准，PIPE_BUF的最小值为512字节，而在大多数现代Linux系统中，PIPE_BUF的值通常为4096字节。

/******************************************************************
 * 功能：有名管道处理数据读取回调函数类型
 * 输出参数：
 *      fd：有名管道的句柄
 *      buffer：读取的数据存放缓存空间
 *      size：读取数据的大小
 *      context：调用的上下文实例
 * ****************************************************************/
typedef void (*pfn_fifo_readdata_callback)(int fd, void* buffer, size_t size, void *context);

#ifdef __linux__
/******************************************************************
 * 功能：创建有名管道
 *   注：多进程通信时，有名管道需遵循谁创建谁销毁的原则；文件路径目录需要存在。
 * 输入参数：
 *      fifo_path：通信双方约定的相同有名管道路径信息
 * 返回值：
 *      int：操作结果，小于0 -- 失败，0 -- 成功
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT int fifoutil_create(const char* fifo_path);

/******************************************************************
 * 功能：销毁有名管道，注：多进程通信时，有名管道需遵循谁创建谁销毁的原则
 * 输入参数：
 *      fifo_path：通信双方约定的相同有名管道路径信息
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT void fifoutil_destroy(const char* fifo_path);
#endif

/******************************************************************
 * 功能：打开有名管道，需先创建再打开
 * 输入参数：
 *      fifo_path：通信双方约定的相同有名管道路径信息
 *      flags：操作权限标识
 * 注：linux平台上如O_WRONLY、O_RDONLY、或者与O_NONBLOCK进行或运算，如O_RDONLY | O_NONBLOCK，O_WRONLY | O_NONBLOCK
 * 注：windows平台管道的服务端使用FIFO_SERVER，客户端使用FIFO_CLIENT。
 * 返回值：
 *      int：有名管道的文件句柄fd信息，小于0 -- 失败，大于等于0 -- 成功
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT int fifoutil_open(const char* fifo_path, int flags);

/******************************************************************
 * 功能：关闭有名管道
 * 输入参数：
 *      fd：打开有名管道时获取的文件句柄
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT void fifoutil_close(int fd);

/******************************************************************
 * 功能：设置有名管道为非阻塞模式
 * 输入参数：
 *      fd：打开有名管道时获取的文件句柄
 * 返回值：
 *      int：操作结果，小于0 -- 失败，0 -- 成功
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT int fifoutil_set_nonblocking(int fd);

/******************************************************************
 * 功能：设置有名管道处理数据回调函数
 * 输出参数：
 *      pfn：回调函数
 *      context：调用的上下文实例
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT void fifoutil_set_readdata_callback(pfn_fifo_readdata_callback pfn, void *context);

/******************************************************************
 * 功能：开始有名管道自动读取数据的线程
 * 输出参数：
 *      fd：打开有名管道时获取的文件句柄
 *      flag：运行的标识，windows平台上使用，取值FIFO_SERVER或者FIFO_CLIENT
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT void fifoutil_loop_start(int fd, int flag);

/******************************************************************
 * 功能：停止有名管道自动读取数据的线程
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT void fifoutil_loop_stop();

/******************************************************************
 * 功能：从有名管道中读取数据
 * 输入参数：
 *      fd：有名管道的fd
 *      buffer：读取数据的缓存空间
 *      buf_size：数据缓存空间的大小
 * 返回值：
 *      int：读取结果，大于等于0 -- 成功，具体读取数据的大小，-1 -- 不成功
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT int fifoutil_read(int fd, char* buffer, size_t buf_size);

/******************************************************************
 * 功能：把数据写入有名管道中
 * 输入参数：
 *      fd：有名管道的fd
 *      buffer：待写入数据的缓存空间
 *      size：数据大小
 * 返回值：
 *      int：写入结果，0 -- 成功，非0 -- 不成功
 * ****************************************************************/
FIFOUTIL_DLL_EXPORT int fifoutil_write(int fd, const char* buffer, size_t size);


#ifdef __cplusplus
} // extern "C"
#endif

#endif // fifo_util_h
